package com.ruoyi.factorydata.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.ruoyi.common.utils.CacheSupportUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.factorydata.domain.*;
import com.ruoyi.factorydata.domain.dto.StationDataDTO;
import com.ruoyi.factorydata.domain.vo.StationDataVo;
import com.ruoyi.factorydata.mapper.*;
import com.ruoyi.factorydata.service.IProcessStationRelationService;
import com.ruoyi.factorydata.service.IStationDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 工位数据Service业务层处理
 *
 * @author ruoyi
 * @date 2025-06-23
 */
@Service
public class StationDataServiceImpl extends ServiceImpl<StationDataMapper, StationData> implements IStationDataService {
    @Autowired
    private StationDataMapper stationDataMapper;

    @Autowired
    private ProductionLineDataMapper productionLineDataMapper;

    @Autowired
    private WorkshopDataMapper workshopDataMapper;

    @Autowired
    private FactoryDataMapper factoryDataMapper;

    @Autowired
    private EquipmentDataMapper equipmentDataMapper;

    @Autowired
    private IProcessStationRelationService processStationRelationService;

    @Autowired
    private EquipmentTypeMapper equipmentTypeMapper;


    /**
     * 查询工位数据
     *
     * @param id 工位数据主键
     * @return 工位数据
     */
    @Override
    public StationData selectStationDataById(Long id) {
        return stationDataMapper.selectStationDataById(id);
    }

    /**
     * 查询工位数据列表
     *
     * @param stationDataDTO 工位数据
     * @return 工位数据
     */
    @Override
    public List<StationDataVo> selectStationDataList(StationDataDTO stationDataDTO) {
        StationData stationData = new StationData();
        stationData.setProductionLineId(stationDataDTO.getProductionLineId());
        stationData.setName(stationDataDTO.getName());
        stationData.setStationCode(stationDataDTO.getStationCode());
        stationData.setEquipmentDataId(stationDataDTO.getEquipmentDataId());
        stationData.setEquipmentDatatype(stationDataDTO.getEquipmentDatatype());
        List<StationData> stationDataList = stationDataMapper.selectStationDataList(stationData);

        Map<Long,String> deviceTypeCache=new HashMap<>();
        List<StationDataVo> stationDataVos = stationDataList.stream().map(station -> {
            WorkshopData workshopData =null;
            FactoryData factoryData=null;
            ProductionLineData productionLineData = productionLineDataMapper.selectProductionLineDataById(station.getProductionLineId());
            if(productionLineData!=null){
                workshopData = workshopDataMapper.selectWorkshopDataById(productionLineData.getWorkshopId());
                factoryData = factoryDataMapper.selectFactoryDataById(workshopData.getFactoryId());
            }

            List<EquipmentData> equipmentDataList = equipmentDataMapper.selectList(new QueryWrapper<EquipmentData>().lambda()
                    .eq(EquipmentData::getStationId, station.getId()));
            Long equipmentId =null;
            String equipmentName =null;
            String equipmentType =null;
            if(equipmentDataList!=null&&equipmentDataList.size()>0){
                equipmentId = equipmentDataList.get(0).getId();
                equipmentName = equipmentDataList.get(0).getEquipmentName();
                Long typeId = equipmentDataList.get(0).getTypeId();
                equipmentType = CacheSupportUtils.getFromCacheOrDB(typeId, deviceTypeCache, equipmentTypeMapper::selectEquipmentTypeById, EquipmentType::getTypeName, false);
            }

            return StationDataVo.builder()
                    .id(station.getId())
                    .name(station.getName())
                    .stationCode(station.getStationCode())
                    .productionLineId(Optional.ofNullable(productionLineData).map(ProductionLineData::getId).orElse(null))
                    .productionLineName(Optional.ofNullable(productionLineData).map(ProductionLineData::getName).orElse("-"))
                    .workshopId(Optional.ofNullable(workshopData).map(WorkshopData::getId).orElse(null))
                    .workshopName(Optional.ofNullable(workshopData).map(WorkshopData::getName).orElse("-"))
                    .factoryId(Optional.ofNullable(factoryData).map(FactoryData::getId).orElse(null))
                    .factoryName(Optional.ofNullable(factoryData).map(FactoryData::getFactoryName).orElse("-"))
                    .equipmentDataList(equipmentDataList)
                    .equipmentId(equipmentId)
                    .equipmentName(equipmentName)
                    .equipmentType(equipmentType)
                    .remarks(station.getRemarks())
                    .delFlag(station.getDelFlag())
                    .version(station.getVersion())
                    .createBy(station.getCreateBy())
                    .createTime(station.getCreateTime())
                    .updateTime(station.getUpdateTime());
        }).map(StationDataVo.StationDataVoBuilder::build).collect(Collectors.toList());
        Page<StationData> queryData=(Page<StationData>)stationDataList;
        Page<StationDataVo> page = new Page<>(queryData.getPageNum(), queryData.getPageSize());
        page.setTotal(queryData.getTotal());
        page.addAll(stationDataVos);
        return page;
    }

    @Override
    public List<StationDataVo> selectStationDataByDeviceList(StationDataDTO stationDataDTO) {
        StationData stationData = new StationData();
        stationData.setProductionLineId(stationDataDTO.getProductionLineId());
        stationData.setName(stationDataDTO.getName());
        stationData.setStationCode(stationDataDTO.getStationCode());
        stationData.setEquipmentDataId(stationDataDTO.getEquipmentDataId());
        stationData.setEquipmentDatatype(stationDataDTO.getEquipmentDatatype());
        List<StationData> stationDataList = stationDataMapper.selectStationDataByDeviceList(stationData);

        Map<Long,String> deviceTypeCache=new HashMap<>();
        List<StationDataVo> stationDataVos = stationDataList.stream().map(station -> {
            WorkshopData workshopData =null;
            FactoryData factoryData=null;
            ProductionLineData productionLineData = productionLineDataMapper.selectProductionLineDataById(station.getProductionLineId());
            if(productionLineData!=null){
                workshopData = workshopDataMapper.selectWorkshopDataById(productionLineData.getWorkshopId());
                factoryData = factoryDataMapper.selectFactoryDataById(workshopData.getFactoryId());
            }

            List<EquipmentData> equipmentDataList = equipmentDataMapper.selectList(new QueryWrapper<EquipmentData>().lambda()
                    .eq(EquipmentData::getStationId, station.getId()));
            String equipmentType =null;
            if(equipmentDataList!=null&&equipmentDataList.size()>0){
                Long typeId = station.getEquipmentType();
                equipmentType = CacheSupportUtils.getFromCacheOrDB(typeId, deviceTypeCache, equipmentTypeMapper::selectEquipmentTypeById, EquipmentType::getTypeName, false);
            }
            return StationDataVo.builder()
                    .id(station.getId())
                    .name(station.getName())
                    .stationCode(station.getStationCode())
                    .productionLineId(Optional.ofNullable(productionLineData).map(ProductionLineData::getId).orElse(null))
                    .productionLineName(Optional.ofNullable(productionLineData).map(ProductionLineData::getName).orElse("-"))
                    .workshopId(Optional.ofNullable(workshopData).map(WorkshopData::getId).orElse(null))
                    .workshopName(Optional.ofNullable(workshopData).map(WorkshopData::getName).orElse("-"))
                    .factoryId(Optional.ofNullable(factoryData).map(FactoryData::getId).orElse(null))
                    .factoryName(Optional.ofNullable(factoryData).map(FactoryData::getFactoryName).orElse("-"))
                    .equipmentDataList(equipmentDataList)
                    .equipmentId(station.getEquipmentId())
                    .equipmentName(station.getEquipmentName())
                    .equipmentType(equipmentType)
                    .remarks(station.getRemarks())
                    .delFlag(station.getDelFlag())
                    .version(station.getVersion())
                    .createBy(station.getCreateBy())
                    .createTime(station.getCreateTime())
                    .updateTime(station.getUpdateTime());
        }).map(StationDataVo.StationDataVoBuilder::build).collect(Collectors.toList());
        Page<StationData> queryData=(Page<StationData>)stationDataList;
        Page<StationDataVo> page = new Page<>(queryData.getPageNum(), queryData.getPageSize());
        page.setTotal(queryData.getTotal());
        page.addAll(stationDataVos);
        return page;
    }

    /**
     * 新增工位数据
     *
     * @param stationData 工位数据
     * @return 结果
     */
    @Override
    public int insertStationData(StationData stationData) {
                stationData.setCreateTime(DateUtils.getNowDate());
            return stationDataMapper.insertStationData(stationData);
    }

    /**
     * 修改工位数据
     *
     * @param stationData 工位数据
     * @return 结果
     */
    @Transactional
    @Override
    public int updateStationData(StationData stationData) {
                stationData.setUpdateTime(DateUtils.getNowDate());
        int i = stationDataMapper.updateStationData(stationData);
        if (i > 0){
            //获取生产线数据
            ProductionLineData productionLineData = productionLineDataMapper.selectById(stationData.getProductionLineId());
            //获取车间数据
            WorkshopData workshopData = workshopDataMapper.selectById(productionLineData.getWorkshopId());
            //获取工厂数据
            FactoryData factoryData = factoryDataMapper.selectById(workshopData.getFactoryId());
            UpdateWrapper<ProcessStationRelation> updateWrapper = new UpdateWrapper<>();
            updateWrapper.lambda()
                    .set(ProcessStationRelation::getStationName,stationData.getName())
                    .set(ProcessStationRelation::getStationCode,stationData.getStationCode())
                    .set(ProcessStationRelation::getProductionLineId,stationData.getProductionLineId())
                    .set(ProcessStationRelation::getProductionLineName, productionLineData.getName())
                    .set(ProcessStationRelation::getWorkshopId, workshopData.getId())
                    .set(ProcessStationRelation::getWorkshopName, workshopData.getName())
                    .set(ProcessStationRelation::getFactoryId, factoryData.getId())
                    .set(ProcessStationRelation::getFactoryName, factoryData.getFactoryName())
                    .eq(ProcessStationRelation::getStationId,stationData.getId());
           processStationRelationService.update(updateWrapper);
        }
        return i;
    }

    /**
     * 批量删除工位数据
     *
     * @param ids 需要删除的工位数据主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteStationDataByIds(Long[] ids) {
        int i = stationDataMapper.deleteBatchIds(Arrays.stream(ids).collect(Collectors.toList()));
        if (i > 0){
            processStationRelationService.remove(new QueryWrapper<ProcessStationRelation>().lambda().in(ProcessStationRelation::getStationId,ids));
        }
        return i;
    }

    /**
     * 删除工位数据信息
     *
     * @param id 工位数据主键
     * @return 结果
     */
    @Override
    public int deleteStationDataById(Long id) {
        return stationDataMapper.deleteStationDataById(id);
    }
}